//
// Created by tongj on 2024/1/13.
//

#ifndef _BUFFER_CUH_
#define _BUFFER_CUH_

template<typename T>
tbs::byte tbs::buffer::Buffer::read(Buffer::readAction<T> act) CONST {

  if (act == nullptr) {
	return empty_func;
  }
  if (_data == nullptr || _len == 0 || _cap == 0) {
	return error;
  }
  size_t sl = sizeof(T);
  size_t __len = _len / sl, __cap = _cap / sl;
  bool stop = false;
  T *s = (T *)_data.get();
  for (size_t i = 0; i < __len && i < __cap && !stop; i++) {
	act(s[i], i, stop);
  }
  return stop ? stopped : success;
}

template<typename T>
void tbs::buffer::Buffer::write_t(const T &value) {
  write_f(&value, sizeof(T), 0);
}

template<typename T>
T &tbs::buffer::Buffer::seek(const size_t &index) {
  auto source = (T *)_data.get();
  return *(source + index);
}

template<class T>
CONST T &tbs::buffer::Buffer::seek(CONST size_t &i) CONST {
  auto source = (T *)_data.get();
  return *(source + i);
}

template<typename T>
size_t tbs::buffer::Buffer::cap_t() CONST NO_EXCEPT {
  return cap() / sizeof(T);
}

template<class T>
size_t tbs::buffer::Buffer::len_t() CONST NO_EXCEPT {
  return len() / sizeof(T);
}

template<class T>
void tbs::buffer::Buffer::append_t(T &&source) {
  write_f(&source, sizeof(T), this->len(), true);
}

template<typename T>
tbs::buffer::BufferIteratorFactory<T>::BufferIteratorFactory(Buffer &ref)
	: ref(ref) {

}

template<typename T>
tbs::buffer::BufferIterator<T> tbs::buffer::BufferIteratorFactory<T>::begin() noexcept {
  return tbs::buffer::BufferIterator<T>(&ref, 0);
}

template<typename T>
tbs::buffer::BufferIterator<T> tbs::buffer::BufferIteratorFactory<T>::end() noexcept {
  return tbs::buffer::BufferIterator<T>(&ref, ref.len_t<T>());
}

template<typename T>
tbs::buffer::BufferIteratorFactory<T> tbs::buffer::Buffer::asIterator() {
  return tbs::buffer::BufferIteratorFactory<T>(*this);
}

#endif //_BUFFER_CUH_